package com.time.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.time.domain.Product;
import com.time.domain.ProductCategory;
import com.time.service.ProductCategoryService;
import com.time.service.ProductService;
import com.time.util.SessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author 张龙佼
 * @Description 商品信息 controller
 * @since 2020-10-14
 */

@Controller
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;
    @Autowired
    private ProductCategoryService productCategoryService;

    /**
     * @param model 封装相应商品数据
     * @param id    商品ID
     * @return 请求转发至前台商品详细页面
     * @Description 根据商品ID查询商品详细数据
     */
    @GetMapping("/product_info")
    public String productInfo(Model model, Integer id) {
        Product product = productService.getById(id);

        model.addAttribute("product", product);
        return "product-view";
    }

    /**
     * @param model     封装相应分页商品数据
     * @param pcChildId 商品二级分类ID
     * @param page      当前页和每页显示数量
     * @return 请求转发至前台商品列表页面
     * @Description 根据商品二级分类ID查询商品数据
     */
    @GetMapping("/category")
    public String productCategory(Model model, Integer pcChildId, Page<Product> page) {
        // 由于页面无法选择每页显示数据，所以默认每页显示8条留言数据
        page.setSize(8);
        Page<Product> productPage = productService.getProductByPcChildId(pcChildId, page);

        model.addAttribute("productPage", productPage);
        model.addAttribute("totalPage", productPage.getPages());
        return "product-list";
    }

    /**
     * @param session 储存购物车至session
     * @param id      商品ID
     * @return 重定向发至购物页面
     * @Description 将商品添加至购物车
     */
    @GetMapping("/shopping_cart")
    public String shoppingCart(HttpSession session, Integer id) {
        // 用户在首页点击购物车按钮
        if (id == null) {
            return "redirect:/order/shopping";
        }

        // 根据商品id查询商品数据
        Product product = productService.getById(id);
        boolean flag = false;    // 此商品是否在购物车标识

        // 构建购物车
        List<Product> cartList = (List<Product>) session.getAttribute(Product.SHOPPING_CART_IN_SESSION);
        if (cartList == null) {
            cartList = new ArrayList<>(20);
        }

        // 判断目标商品是否在购物车中，若在则数量+1
        for (Product productTemp : cartList) {
            if (product.getId().equals(productTemp.getId())) {
                productTemp.setCount(productTemp.getCount() + 1);
                flag = true;
                break;
            }
        }

        // 如果目标商品不在购物车，则添加到购物车
        if (!flag) {
            product.setCount(1);
            cartList.add(product);
        }

        // 将购物车存储到session中
        SessionUtils.setShoppingCartSession(session, cartList);
        return "redirect:/order/shopping";
    }

    /**
     * @param model 封装分页商品数据
     * @param page  当前页和每页显示数量
     * @return 请求转发至后台商品列表页面
     * @Description 分页查询商品数据给后台
     */
    @RequestMapping("/list")
    public String products(Model model, Page<Product> page) {
        // 由于页面无法选择每页显示数据，所以默认每页显示8条留言数据
        page.setSize(8);
        Page<Product> productPage = productService.page(page);

        model.addAttribute("productPage", productPage);
        model.addAttribute("totalPage", productPage.getPages());
        return "manage/product";
    }

    /**
     * @param model 封装商品分类数据和商品回显数据
     * @param id    商品ID
     * @return ID为空时，请求转发至添加页面，否则请求转发至更新页面
     * @Description 根据商品ID是否为空，跳转至商品添加或更新页面
     */
    @RequestMapping("/input")
    public String input(Model model, Integer id) {
        // 加载所有商品分类信息并封装
        loadProductCategory(model);

        if (id == null) {
            return "/manage/product-add";
        } else {
            Product product = productService.getById(id);
            model.addAttribute("product", product);
            return "manage/product-modify";
        }
    }

    /**
     * @param product    更新的商品对象
     * @param uploadFile 更新的商品图片
     * @param req        请求对象，获取服务器根路径
     * @return 根根据添加和更新商品结果，请求转发至相应页面
     * @Description 更新商品数据
     */
    @PostMapping("/update")
    public String update(Product product, MultipartFile uploadFile,
                         HttpServletRequest req) {

        boolean addProductResult = false;       // 添加商品信息结果
        boolean updateProductResult = false;    // 更新商品信息结果

        // 商品id不为空，更新商品信息
        if (product.getId() != null) {
            // 商品文件不为空，上传文件
            if (uploadFile.getSize() > 0) {
                String newFileName = upload(req, uploadFile);
                product.setFileName("/upload/images/" + newFileName);
            }
            updateProductResult = productService.updateById(product);

        } else {     // 商品id为空，添加商品信息
            if (uploadFile.getSize() > 0) {
                // 根据商品子分类获取商品分类信息，并将父分类赋给商品
                ProductCategory productCategory = productCategoryService.getById(product.getPcChildId());
                product.setPcId(productCategory.getParentId());

                String newFileName = upload(req, uploadFile);    // 文件上传
                // 将图片路径名称添加至商品对象 and 添加商品信息
                product.setFileName("/upload/images/" + newFileName);
                addProductResult = productService.save(product);
            }
        }

        // 根据添加和更新商品结果，请求转发至相应页面
        return JumpPage.backJumpPage(addProductResult || updateProductResult || uploadFile.getSize() > 0);
    }

    /**
     * @param req        请求对象，获取服务器根路径
     * @param uploadFile 上传的文件
     * @return 返回新文件名称
     * @Description 文件上传
     */
    private String upload(HttpServletRequest req, MultipartFile uploadFile) {
        String newFileName = "";    // 新文件名

        if (uploadFile.getSize() > 0) {
            // 获取原文件名称 and 及构建文件新名称
            String oldFilename = uploadFile.getOriginalFilename();
            newFileName = UUID.randomUUID()
                    + oldFilename.substring(oldFilename.lastIndexOf("."));

            // 获取根路径 and 构建图片路径
            String rootPath = req.getServletContext().getRealPath("/");
            rootPath = rootPath + "upload/images/" + newFileName;

            // 商品图片上传
            File dest = new File(rootPath);
            try {
                uploadFile.transferTo(dest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return newFileName;
    }

    /**
     * @param id 商品ID
     * @return 根据删除结果，请求转发至相应页面
     * @Description 根据商品ID删除商品数据
     */
    @RequestMapping("/delete")
    public String delete(Integer id) {
        boolean removeProduct = productService.removeById(id);

        // 根据删除结果，请求转发至相应页面
        return JumpPage.backJumpPage(removeProduct);
    }

    /**
     * @param model 封装商品分类数据
     * @Description 加载所有商品分类数据
     */
    private void loadProductCategory(Model model) {
        List<ProductCategory> productCategories = productCategoryService.productCategories();
        model.addAttribute("productCategories", productCategories);
    }

    /**
     * @param model 封装商品分类数据
     * @return 请求转发至后台商品分类页面
     * @Description 查询商品分类数据给后台
     */
    @RequestMapping("/category/list")
    public String categoryList(Model model) {
        // 加载所有商品分类信息并封装
        loadProductCategory(model);

        return "manage/productClass";
    }

    /**
     * @param model 封装商品分类回显数据
     * @param id    商品分类ID
     * @return 商品ID为空时，请求转发至添加页面，否则请求转发至更新页面
     * @Description 根据商品分类ID是否为空，跳转至商品分类添加或更新页面
     */
    @RequestMapping("/category/input")
    public String categoryInput(Model model, Integer id) {
        // 加载所有商品分类信息并封装
        loadProductCategory(model);

        if (id == null) {
            return "/manage/productClass-add";
        } else {
            ProductCategory productCategory = productCategoryService.getById(id);
            model.addAttribute("productCategory", productCategory);
            return "manage/productClass-modify";
        }
    }

    /**
     * @param productCategory 添加后更新商品分类对象
     * @return 根据添加或更新结果，请求转发至相应页面
     * @Description 根据商品ID是否为空，添加或更新商品分类数据
     */
    @PostMapping("/category/update")
    public String categoryUpdate(ProductCategory productCategory) {
        boolean addProductCategory = false;       //添加商品分类结果
        boolean updateProductCategory = false;    //更新商品分类结果

        // 更新and添加 商品分类信息
        if (productCategory.getId() != null) {
            updateProductCategory = productCategoryService.updateProductCategory(productCategory);
        } else {
            addProductCategory = productCategoryService.addProductCategory(productCategory);
        }

        // 根据添加或更新结果，请求转发至相应页面
        return JumpPage.backJumpPage(addProductCategory || updateProductCategory);
    }

    /**
     * @param id 商品分类ID
     * @return 根据删除是否成功，请求转发至相应页面
     * @Description 根据商品分类ID删除商品分类信息
     */
    @RequestMapping("/category/delete")
    public String categoryDelete(Integer id) {
        boolean deleteProductCategory = productCategoryService.removeById(id);

        // 根据删除结果，请求转发至相应页面
        return JumpPage.backJumpPage(deleteProductCategory);
    }
}
